package game.utility;

import java.io.File;
import java.io.IOException;

import javax.sound.sampled.AudioFileFormat;
import javax.sound.sampled.AudioInputStream;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;
import javax.sound.sampled.UnsupportedAudioFileException;

public class SoundUtility {

	public static enum Sound {
		BUMP(ResourceUtility.getAudioPath("bump.wav")), JUMP(ResourceUtility.getAudioPath("jump.wav"));
		private byte[] bytes;
		private AudioFileFormat fileFormat;
		private SourceDataLine sourceDataLine;

		private Sound(String filePath) {
			try {
				fileFormat = AudioSystem.getAudioFileFormat(new File(filePath));
				AudioInputStream inpStream = AudioSystem.getAudioInputStream(new File(filePath));
				bytes = new byte[fileFormat.getFrameLength() * fileFormat.getFormat().getFrameSize()];
				inpStream.read(bytes);
			} catch (UnsupportedAudioFileException | IOException e) {
				throw new RuntimeException(e);
			}
		}

		public void play() {
			try {
				sourceDataLine = AudioSystem.getSourceDataLine(fileFormat.getFormat());
			} catch (LineUnavailableException e) {
				e.printStackTrace();
			}
			try {
				sourceDataLine.open(fileFormat.getFormat());
			} catch (LineUnavailableException e) {
				e.printStackTrace();
			}
			sourceDataLine.start();
			sourceDataLine.write(bytes, 0, bytes.length);
			sourceDataLine.drain();
			sourceDataLine.close();
		}
	}

	public static class SoundThread extends Thread {
		private final Sound sound;

		public SoundThread(Sound sound) {
			this.sound = sound;
		}

		@Override
		public void run() {
			super.run();
			sound.play();
		}
	}

	public static SoundUtility singleton() {
		return SINGLETON;
	}

	private boolean soundOn = true;

	private static SoundUtility SINGLETON = new SoundUtility();

	public boolean isSoundOn() {
		return soundOn;
	}

	public synchronized void playSound(Sound sound) {
		if (soundOn) {
			new SoundThread(sound).start();
		}
	}

	public void setSoundOn(boolean soundOn) {
		this.soundOn = soundOn;
	}

	public void setSoundOn(String value) {
		boolean soundOn = false;
		if (SettingsUtility.VALUE_SOUND_ON.equals(value)) {
			soundOn = true;
		}
		setSoundOn(soundOn);
	}
}